The Environment Examiner: Where

The where procedure provides a method of examining and modifying environments. Where is a procedure of 0 or 1 arguments that enters a read-execute command loop when called. Unlike a REP loop, this loop reads one letter and treats it as a command to be performed. Scheme will prompt for the one-character command at the bottom of the screen in the Emacs echo area. To give a command, just type the character—you needn't press RETURN.

If called with no arguments, where examines the current REP loop environment. The optional argument can be an environment or an object with an environment associated with it, such as a procedure. Below is an example of where being called at a breakpoint in a Scheme procedure. This illustrates some of the things which can be done with where.

While the where procedure is a very useful debugging aid, using it effectively requires a good understanding of Scheme's environment structures. For this reason you may find it less confusing to use only the C command initially.

Here is a brief description of each where command.

?
Prints a summary of the where command characters.

A
(for all) Displays the bindings in all of the frames in the current environment chain.

C
(for current) Displays the bindings in the current frame.

E
(for eval) Enters a REP loop in the current environment.

N
(for name) Shows the name of procedure that created current environment frame.

P
(for parent) Moves up to the parent of the current environment frame, then does a C command.

Q
(for quit) Exits where.

S
(for son) Move to the son of the current environment frame. This undoes a P command.

V
(for value) Evaluates one expression in the current frame and pretty-prints the result.

W
(for where) Evaluate an expression in the current frame and call where on the result.

Here is an example of using where. The indicators at the left of the user input show the information that would appear in the buffer mode line, and in the prompts in the echo area: $\Longrightarrow$
$\Longrightarrow$ unspecified error `=̀13`


          [1 REP] (define (one x y z)            (define (two x y z)             (define (three x y z)               (bkpt "In procedure three environment"                     (list x y z)))             (three 1 2 3))           (two 4 5 6))

ONE

[1 REP] (one 'a 'b 'c) In procedure three environment (1 2 3) Breakpoint

[2 Break] (where) Environment Inspector [3 Where] c Frame created by the procedure THREE. Depth (relative to starting frame): 0 Has bindings:

X = 1 Y = 2 Z = 3

The C command prints the variable bindings in the currently selected environment frame. Since the breakpoint occurred inside the execution of the procedure three, the current environment is the one resulting from the application of C to the arguments 1 2 3.

The P command moves to the frame in which three was defined. In this case the parent is the frame created by the application of the procedure two to the arguments 4 5 6. $\Longrightarrow$
$\Longrightarrow$ unspecified error `=̀13`


          [3 Where] p Frame created by the procedure TWO. Depth (relative to starting frame): 1 Has bindings:

X = 4 Y = 5 Z = 6 THREE = #<COMPOUND-PROCEDURE THREE>

[3 Where] p Frame created by the procedure ONE. Depth (relative to starting frame): 2 Has bindings:

X = A Y = B Z = C TWO = #<COMPOUND-PROCEDURE TWO>

[3 Where] p Frame created by a MAKE-PACKAGE special form. Depth (relative to starting frame): 3 Has bindings:

USER-INITIAL-ENVIRONMENT = #<ENVIRONMENT 13679124> ONE = #<COMPOUND-PROCEDURE ONE>

Here we have reached the user initial environment in which the top most procedure one was defined. That's enough … $\Longrightarrow$
$\Longrightarrow$ unspecified error `=̀13`

          [3 Where] q
and we are back in the REP loop where we started. We can continue the program by typing (proceed).

Notice that we could stop at any environment and create a REP loop in it by using the E command. This allows you, for example, to define missing variables when you encounter an unbound variable error. Similarly, you can use the V (one expression) command to evaluate a single expression in any of the frames in the environment chain.